import * as THREE from "../../three/build/three.module.js";
import {GLTFLoader} from "../../three/examples/jsm/loaders/GLTFLoader.js";
import {OrbitControls} from "../../three/examples/jsm/controls/OrbitControls.js";
import Stats from "../../three/examples/jsm/libs/stats.module.js";

class Main{
    scene; camera; renderer;
    control; stats;
    init(){
        this.initThree();
        this.createScene();
    }
    initThree(){
        this.scene = new THREE.Scene();
        this.camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 0.1, 10000);
        this.renderer = new THREE.WebGLRenderer({ antialias: true, logarithmicDepthBuffer: true });

        this.camera.position.set(-30,38,0);
        this.renderer.setSize(window.innerWidth,window.innerHeight)
        document.body.appendChild(this.renderer.domElement);
        this.control = new OrbitControls(this.camera, this.renderer.domElement);
        this.control.target = new THREE.Vector3(0,35,0);
        this.control.update();

        this.stats = new Stats();
        document.body.appendChild( this.stats.dom );
    }
    createScene(){
        let scene = this.scene;
        const gltfLoader = new GLTFLoader();
        let that = this;
        gltfLoader.load('./thee.gltf',
            function(gltf){
                that.scene.add(gltf.scene);
            }
        );

        const light1 = new THREE.AmbientLight(0xffffff, 0.2);
        scene.add(light1);

        const light2 = new THREE.DirectionalLight(0xffffff, 1);
        light2.target = (() => {
                let target = new THREE.Object3D();
                target.position.set(2,-1,1);
                scene.add(target);
                return target;
            })();
        window.light2 = light2;
        scene.add(light2);

        // const light3 = new THREE.PointLight(0xffffff, 1, 1000);
        // light3.position.set(100,100,100);
        // scene.add(light3);
        // let cont = new OrbitControls(light3, this.renderer.domElement);
        // cont.autoRotate=true;
        // window.light3 = light3;
        // window.cont = cont;
    }
    test(){
        let mesh = new THREE.Mesh(
            new THREE.BoxBufferGeometry(),
            new THREE.MeshBasicMaterial({color:0xff0000})
        );
        mesh.position.set(25.6,40,0);
        this.scene.add(mesh);
    }

    setCameraPosByDis(dis){
        const cam = this.camera;
        const dir = cam.position.clone();
        dir.sub(this.control.target).normalize();

        const pos = dir.clone();
        pos.multiplyScalar(dis).add(this.control.target);
        
        cam.position.copy(pos);
    }

    setCameraFovByDis(dis){
        const oldFov = this.camera.fov;
        const v3 = this.camera.position.clone();
        const oldDis = v3.sub(this.control.target).length();
        const a = Math.tan(oldFov/360*2*Math.PI) * oldDis;
        
        const newFov = Math.atan(a/dis) * 360 / 2 / Math.PI;
        this.camera.fov = newFov;
        this.camera.updateProjectionMatrix();
    }

    cameraMoveTo(dis){
        this.setCameraFovByDis(dis);
        this.setCameraPosByDis(dis);
    }


    animate(m){
        let _ = m;
        requestAnimationFrame(function(){
            _.animate(_);
        });

        let dis = Math.sin(Date.now()/1000)*2000 + 1000;
        dis = dis > 0 ? dis + 20 : 20;
        _.cameraMoveTo(dis);


        _.stats.update();
        _.renderer.render(_.scene, _.camera);
    }
}

let main = new Main();
main.init();
main.animate(main);
main.test();

window.main = main;